package com.springboot.demo.io.aio;

import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;

import com.springboot.demo.io.Constants;

/**
 * AIO服务处理器
 *
 * @author supu
 * @date 2019-12-03 17:17
 **/
public class AIOServerHandler implements CompletionHandler<AsynchronousSocketChannel,AIOServer> {
    @Override
    public void completed(AsynchronousSocketChannel result, AIOServer attachment) {
        // 保证多个客户端都可以阻塞
        attachment.serverSocketChannel.accept(attachment,this);
        read(result);
    }

    // 读取数据
    private void read(final AsynchronousSocketChannel socketChannel) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(Constants.BUFFER_SIZE);
        socketChannel.read(byteBuffer, byteBuffer, new CompletionHandler<Integer, ByteBuffer>() {
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                // 读取之后重置标记位
                attachment.flip();
                // 获取读取的数据
                String resultData = new String(attachment.array()).trim();
                System.out.println("AIO server received data:" + resultData);
                //
                String responseContent = resultData + " response";
                write(socketChannel, responseContent);
            }

            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                exc.printStackTrace();
            }
        });
    }

    private void write(AsynchronousSocketChannel socketChannel, String responseContent) {
        try {
            ByteBuffer byteBuffer = ByteBuffer.allocate(Constants.BUFFER_SIZE);
            // 数据放入缓冲区中
            byteBuffer.put(responseContent.getBytes());
            byteBuffer.flip();
            // 缓冲区中数据写入到通道中
            socketChannel.write(byteBuffer).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void failed(Throwable exc, AIOServer attachment) {
        exc.printStackTrace();
    }
}
